/**
 *  EKology - An Ecosystem Simulation Framework
 *  Copyright (C) 2008  Aarón Tavío - aaron.tavio at gmail.com - ULPGC
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package net.ekology.graphics;

import net.ekology.ekosystem.datatypes.EKVector;

import java.awt.*;
import java.awt.geom.*;
import java.io.*;


/**
 * @author Aarón Tavío - aaron.tavio at gmail.com
 * @version 1.0.0 - 20081019-1700
 */
public class EKPainter implements Serializable {
    private Color oDefaultFillColor = Color.GRAY;
    private Color oDefaultDrawColor = Color.WHITE;
    transient private BasicStroke oDefaultStroke;
    
    private Ellipse2D.Double oDummyBody;
    private Ellipse2D.Double oDummySpot;
    transient private Area oDummy;
    
    
    
    private static class SingletonHolder { // Inner class
        private final static EKPainter INSTANCE = new EKPainter();
    }
 
    
    public static EKPainter getInstance() { //
        return SingletonHolder.INSTANCE;
    }
    
    public EKPainter() {
        oDummyBody = new Ellipse2D.Double(-50,-50,100,100);
        oDummySpot = new Ellipse2D.Double(-4,36,8,8);
        
        initialize();
    }
    
    private void initialize() {
        oDefaultStroke = new BasicStroke(1f);
        oDummy = new Area(oDummyBody);
        oDummy.subtract(new Area(oDummySpot));
    }
    
    public void drawDummy(Graphics2D g2) {
        drawDummy(g2, new EKVector(0,0),new EKVector(0,1),1,oDefaultDrawColor,oDefaultFillColor);
    }
    
    
    public void drawDummy(Graphics2D g2, EKVector oPosition) {
        drawDummy(g2, oPosition,new EKVector(0,1),1,oDefaultDrawColor,oDefaultFillColor);
    }
    
    
    public void drawDummy(Graphics2D g2, EKVector oPosition, EKVector oOrientation) {
        drawDummy(g2, oPosition,oOrientation,1,oDefaultDrawColor,oDefaultFillColor);
    }
    
    
    public void drawDummy(Graphics2D g2, EKVector oPosition, EKVector oOrientation, double dScale) {
        drawDummy(g2, oPosition,oOrientation,dScale,oDefaultDrawColor,oDefaultFillColor);
    }
    
    
    public void drawDummy(Graphics2D g2, EKVector oPosition, EKVector oOrientation, double dScale, Color oBorder) {
        drawDummy(g2, oPosition,oOrientation,dScale,oBorder,oDefaultFillColor);
    }
    
    /**
     * Draws a dummy object using the specified parameters
     * 
     * @param g2 Graphics2D object to paint in
     * @param oPosition the position of the dummy
     * @param oOrientation a vector indicating the orientation to look at
     * @param dScale should be greather than 0.25
     * @param oBorder the color of the border
     * @param oInterior the color of the interior
     */
    public void drawDummy(Graphics2D g2, EKVector oPosition, EKVector oOrientation, double dScale, Color oBorder, Color oInterior) {
        Area oNewDummy;
        
        oNewDummy = (Area) oDummy.clone();
        oNewDummy.transform(getTransform(oPosition.getComponent(0),oPosition.getComponent(1),oOrientation.getDirection(),dScale));
        
        g2.setStroke(oDefaultStroke);
        g2.setColor(oBorder);
        g2.draw(oNewDummy);
        g2.setColor(oInterior);
        g2.fill(oNewDummy);
    }
    
    
    public static AffineTransform getTransform(double dXPos, double dYPos, double dRotation, double dScale) {
        AffineTransform oResult;
        
        oResult = AffineTransform.getTranslateInstance(dXPos, dYPos);
        oResult.scale(dScale, dScale);
        oResult.rotate(dRotation);
        
        return oResult;
    }
    
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        initialize();
    }

} // public class EKPainter {